package com.jboltai.resource.embedding;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 每个大模型可用的资源
 */
public class EmbeddingResourceGroup {
    /**
     * 可用资源
     */
    List<EmbeddingResource> validResources = new ArrayList<>();
    /**
     * 当前已用完的等待重置的资源
     */
    List<EmbeddingResource> invalidResources = new ArrayList<>();


    /**
     * 资源id和资源的映射
     */
    Map<String, EmbeddingResource> resourceMap = new HashMap<>();





    /**
     * 移除ai资源
     * @param resource
     */
    void removeResource(EmbeddingResource resource) {
        synchronized (this) {
            validResources.remove(resource);
            invalidResources.remove(resource);
            resourceMap.remove(resource.getId());
        }
    }


    /**
     * 根据id 获取ai资源
     * @param id 如果id是null，返回第一个可用的资源，否则根据id获取
     */
    public EmbeddingResource getResource(String id) {
        synchronized (this) {
            if (validResources.isEmpty()) {
                return null;
            }
            if (id == null) {
                return validResources.get(0);
            }

            for (int i = 0; i < validResources.size(); i++) {
                if (id.equals(validResources.get(i).getId())) {
                    return validResources.get(i);
                }
            }

            return null;
        }
    }



    /**
     * 检测是否有资源,传入id了，就检测有没有对应id的资源，否则检测有没有可用的资源
     * @return
     */
    public boolean hasResource(String resourceId) {
        return resourceId == null ? !resourceMap.isEmpty() : resourceMap.containsKey(resourceId);
    }


    /**
     * 添加ai资源，已存在的不会重复添加
     * @param resource
     */
    public void add(EmbeddingResource resource) {

        synchronized (this) {
            if (resourceMap.containsKey(resource.getId())) {
                throw new RuntimeException("id为" + resource.getId() + "的资源已注册，不可重复注册");
            }
            resource.setResourceGroup(this);
            if (resource.checkAvailable()) {
                validResources.add(resource);
            } else {
                invalidResources.add(resource);
            }
            resourceMap.put(resource.getId(), resource);
        }

    }
    /**
     * 添加ai资源，已存在的不会重复添加
     * @param resource
     */
    public void update(EmbeddingResource resource) {

        synchronized (this) {
            if (resource.checkAvailable()) {
                if (validResources.contains(resource)) return;
                if (invalidResources.contains(resource)) {
                    invalidResources.remove(resource);
                }
                validResources.add(resource);
            } else {
                if (invalidResources.contains(resource)) return;
                if (validResources.contains(resource)) {
                    validResources.remove(resource);
                }
                invalidResources.add(resource);
            }
        }
    }

    /**
     * 将资源移到无效资源列表
     * @param resource
     */
    public void moveToInvalid(EmbeddingResource resource) {
        synchronized (this) {
            if (validResources.contains(resource)) {
                validResources.remove(resource);
            }
            if (invalidResources.contains(resource)) return;
            invalidResources.add(resource);
        }
    }

    /**
     * 将资源移到有效资源列表
     * @param resource
     */
    public void moveToValid(EmbeddingResource resource) {
        synchronized (this) {
            if (invalidResources.contains(resource)) {
                invalidResources.remove(resource);
            }
            if (validResources.contains(resource)) return;
            validResources.add(resource);
        }
    }


    /**
     * 重置资源的频率限制
     */
    public void resetResourceLimit() {
        synchronized (this) {
            resourceMap.values().iterator().forEachRemaining(resource -> {
                resource.resetLimit();
            });
        }
    }


    public int getResourceCount() {
        return resourceMap.size();
    }

    public int getValidResourceCount() {
        return validResources.size();
    }

    public int getInvalidResourceCount() {
        return invalidResources.size();
    }

}
